# chat_service.py
import os
import logging
from typing import Optional, Tuple
from config import app_config
from src.repository.chatMessages_repository import chat_message_repo
from src.repository.chatMessagesFlow_repository import chat_message_flow_repo

# ASR 模块导入
if app_config.ASR_TYPE == "whisper_asr":
    from src.asr.whisper_asr import transcribe_audio
elif app_config.ASR_TYPE == "qwen3_asr":
    from src.asr.qwen3_asr import q3asr_transcribe_audio_file as transcribe_audio_file

# LLM 模块导入
if app_config.LLM_TYPE == "qwen":
    from src.llm.qwen import call_qwen
elif app_config.LLM_TYPE == "ollama":
    from src.llm.ollama import call_ollama

# TTS 模块导入
if app_config.TTS_TYPE == "edge_tts":
    from src.tts.edge_tts_tts import speak
elif app_config.TTS_TYPE == "gpt_sovits":
    from src.tts.gpt_sovits_tts import call_gpt_sovits

logger = logging.getLogger(__name__)

class ChatService:
    """
    聊天服务类，处理整个聊天流程：
    1. 接收音频/文本输入
    2. 调用ASR模块（如果是音频输入）
    3. 调用LLM模块生成响应
    4. 调用TTS模块生成音频响应
    """

    def __init__(self):
        """初始化聊天服务"""
        self.current_character = app_config.CURRENT_CHARACTER

    def process_text_input(self, session_id: int, text_input: str) -> dict:
        """
        处理文本输入
        
        Args:
            session_id: 会话ID
            text_input: 输入文本
            
        Returns:
            dict: 处理结果，包含响应文本和音频路径
        """
        try:
            # 1. 插入消息记录，状态为START
            msg_id = chat_message_repo.create_message(session_id, "START")
            if not msg_id:
                raise Exception("创建消息记录失败")

            # 2. 记录输入文本到消息流程表
            chat_message_flow_repo.log_input_text(msg_id, text_input)

            # 3. 调用LLM模块
            return self._process_with_llm(session_id, msg_id, text_input)
        except Exception as e:
            logger.error(f"处理文本输入时出错: {str(e)}")
            return {
                "error": str(e),
                "message": "处理文本输入时发生错误"
            }

    def process_audio_input(self, session_id: int, audio_file_path: str) -> dict:
        """
        处理音频输入
        
        Args:
            session_id: 会话ID
            audio_file_path: 音频文件路径
            
        Returns:
            dict: 处理结果，包含响应文本和音频路径
        """
        try:
            # 1. 插入消息记录，状态为START
            msg_id = chat_message_repo.create_message(session_id, "START")
            if not msg_id:
                raise Exception("创建消息记录失败")

            # 2. 记录输入音频文件路径到消息流程表
            chat_message_flow_repo.log_input_audio(msg_id, audio_file_path)

            # 3. 更新状态为ASR_PENDING
            chat_message_repo.log_ASR_PENDING(msg_id)

            # 4. 调用ASR模块获取文本
            if app_config.ASR_TYPE == "qwen3_asr":
                input_text = transcribe_audio_file(audio_file_path)
            else:
                input_text = transcribe_audio(audio_file=audio_file_path)
            
            # 5. 记录ASR结果到消息流程表
            chat_message_flow_repo.log_input_text(msg_id, input_text)
            
            # 6. 更新状态为ASR_DONE
            chat_message_repo.log_ASR_DONE(msg_id)

            # 7. 调用LLM模块
            return self._process_with_llm(session_id, msg_id, input_text)
        except Exception as e:
            # 更新状态为ASR_FAILED
            if 'msg_id' in locals():
                chat_message_repo.log_ASR_FAILED(msg_id)
            logger.error(f"处理音频输入时出错: {str(e)}")
            return {
                "error": str(e),
                "message": "处理音频输入时发生错误"
            }

    def _process_with_llm(self, session_id: int, msg_id: int, input_text: str) -> dict:
        """
        使用LLM处理文本并生成响应
        
        Args:
            session_id: 会话ID
            msg_id: 消息ID
            input_text: 输入文本
            
        Returns:
            dict: 处理结果
        """
        try:
            # 1. 更新状态为LLM_PENDING
            chat_message_repo.log_LLM_PENDING(msg_id)

            # 2. 调用LLM模块
            if app_config.LLM_TYPE == "qwen":
                response_text = call_qwen(
                    user_input=input_text,
                    session_id=str(session_id),
                    character=self.current_character,
                    enable_memory=True
                )
            elif app_config.LLM_TYPE == "ollama":
                response_text = call_ollama(
                    prompt=input_text,
                    character=self.current_character
                )
            else:
                raise Exception(f"不支持的LLM类型: {app_config.LLM_TYPE}")

            if not response_text:
                raise Exception("LLM未返回有效响应")

            # 3. 记录LLM响应到消息流程表
            chat_message_flow_repo.log_response_text(msg_id, response_text)

            # 4. 更新状态为LLM_DONE
            chat_message_repo.log_LLM_DONE(msg_id)

            # 5. 调用TTS模块
            return self._process_with_tts(session_id, msg_id, response_text)
        except Exception as e:
            # 更新状态为LLM_FAILED
            chat_message_repo.log_LLM_FAILED(msg_id)
            logger.error(f"调用LLM时出错: {str(e)}")
            return {
                "error": str(e),
                "message": "调用LLM时发生错误"
            }

    def _process_with_tts(self, session_id: int, msg_id: int, response_text: str) -> dict:
        """
        使用TTS处理文本并生成音频
        
        Args:
            session_id: 会话ID
            msg_id: 消息ID
            response_text: 响应文本
            
        Returns:
            dict: 处理结果，包含响应文本和音频路径
        """
        try:
            # 1. 更新状态为TTS_PENDING
            chat_message_repo.log_TTS_PENDING(msg_id)

            # 2. 生成音频文件路径
            audio_output_dir = "/root/code/AI_VTuber/AI_VTuber_Server/static/audio_files/output"
            os.makedirs(audio_output_dir, exist_ok=True)
            audio_file_name = f"response_{msg_id}.mp3"
            audio_file_path = os.path.join(audio_output_dir, audio_file_name)

            # 3. 调用TTS模块
            if app_config.TTS_TYPE == "edge_tts":
                speak(response_text, audio_file_path)
            elif app_config.TTS_TYPE == "gpt_sovits":
                call_gpt_sovits(response_text, "zh", audio_file_path)
            else:
                raise Exception(f"不支持的TTS类型: {app_config.TTS_TYPE}")

            # 4. 记录TTS结果到消息流程表
            chat_message_flow_repo.log_response_audio(msg_id, audio_file_path)

            # 5. 更新状态为TTS_DONE
            chat_message_repo.log_TTS_DONE(msg_id)

            # 6. 更新状态为END
            chat_message_repo.log_END(msg_id)

            # 7. 返回结果
            return {
                "success": True,
                "response_text": response_text,
                "audio_file_path": audio_file_path
            }
        except Exception as e:
            # 更新状态为TTS_FAILED
            chat_message_repo.log_TTS_FAILED(msg_id)
            logger.error(f"调用TTS时出错: {str(e)}")
            return {
                "error": str(e),
                "message": "调用TTS时发生错误"
            }


# 创建全局实例
chat_service = ChatService()